/*******************************************************************************
 * Copyright (c) 2008, 2009 Fabio Mauro - Alberto Terraneo.
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 1.2
 * or any later version published by the Free Software Foundation.
 *     
 * This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied 
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 * See the GNU Free Documentation License for more details.
 *     
 * You should have received a copy of the GNU Free Documentation 
 * License along with this distribution; if not, send a email to authors:
 * aterraneo <at> users.sourceforge.net
 * bigmoby09 <at> users.sourceforge.net
 *******************************************************************************/
package it.blueocean.acanto.aop.logging;

import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;

public class AuditingLoggerInterceptor implements MethodBeforeAdvice, AfterReturningAdvice, MethodInterceptor
{
	private static Log log = null;

	public AuditingLoggerInterceptor()
	{
	}

	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable
	{
		log = LogFactory.getLog(arg2.getClass());
		
		log.info("Beginning method: " + arg0.getName());
	}

	public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable
	{
		log = LogFactory.getLog(arg3.getClass());

		log.info("Ending method: " + arg1.getName());
	}

	public Object invoke(MethodInvocation invocation) throws Throwable
	{
		log = LogFactory.getLog(invocation.getClass());

		StringBuilder logLine = new StringBuilder();
		logLine.append("Calling: ");
		Method m = invocation.getMethod();
		logLine.append(m.getDeclaringClass().getName()).append(".").append(m.getName()).append("(");
		Object[] params = invocation.getArguments();

		if(params != null && params.length > 0)
		{
			int counter = 0;

			for (Object param : params)
			{
				logLine.append(param);

				counter++;

				if(counter < params.length)
				{
					logLine.append(", ");
				}
			}
		}

		logLine.append(")");

		log.debug(logLine);

		Object returnValue = invocation.proceed();

		StringBuilder logReturnLine = new StringBuilder();
		logReturnLine.append("Returned: ").append(returnValue);

		log.debug(logReturnLine);

		return returnValue;
	}

}
